1110100000010101010000010010011111000011101100001111110000000011000110111111101110011001010011001110111010001010010010101100011011001010011011011000101011000011111010011001011111100010011111101110000001100011010100010001110010011000000111111101011110100010101001100101111111110101011010000100011000011110110110000001101110100110000010000010110100000111000001011110010101000101011110001001101111010010 1111010011101110110001101100000010101101000011100111001000011110010100101011111101110001111100010110111011100100101001000001000110000111011100001111110001000010001110010011101100011011010011101110000101000100111101011111110100001110011100101010001000110110110110011011001110110100001000010101111111111000011011000110001111010010000000110110100000110000010110101101011101000101000000110101100111000111 1000011010110001000001001110000110010010011100001000111111111010111001010101000111111001110111110111100011011010101100111100110011000011011100001001011000101001010010010000100011111010100001100110000001001111101001101111010111101000100100101000111000111100011100000100100101010100011010101110111000011111001000011010110010100010010010111101100101100011011111100110010000111000010110100000001011111010 1100100101011001001111000011011010110110010010011010011000010101010100110010010100001111111010011110101110001011101110001011100011100000011011101110110100011011010000001001101100101100111111000001101010011001010100011000001000111111000111001011010001010001000011101100001010110010010111110001101110101110101101100010100111000101011110100001110111100100000100001111100000001010111100101101000001001110 1000000111111110110100101110110010110011000011101011110110111010100010101000000100001100001100011001000101111100010010011100000000110110101000011001101001000100010010101110001100111010100100101111010100010111111110111111111111011101110110111100011111111111001001010011000111001100010011100000010101111001010011000111111110001000011111100000111111011101001001010001100101100111000000110010001101011001 1110010011010110101000100111111010110100101111111111101001111001000000011100010001111011011101111100101100100010100000001111100110011001110110001111010101010101011101010000111110111010001100110001110010110010011110000101111000010001110011001011101011100110110111010010101100100010111000000010011101010000001100011001110001101001001010111011011101000100100110100110001100101000011011010000000110110101 1011011100110011010110011101111010001010111101001111111110111101101010000110100101110100111101000111000000100111111001110000100011111001101000101001011100001000001100011001000111110101101101010010100000011010100101100000000011110000000010011110011010100100000010000100000100010010111010111001100110100001010101011110000111100001110110101001100111110001011010111100111101111001001111001011000010110001 1100101101110100110111000010101100001100111110010101100101101011110000011010101000000111101110011000110000111000100001000110001011011111001111000000100101111110000010011011001100000010001011101100000011000100110011011011101000011111100100001000010101111101000110010010110000101101110001011011000100111100000101111011101110001011111000111000110110110100111001000010001111001011000011110110010101101101 0001111101001100100100010010100000100011011000100111101111011010010010111100100110111101011011011101010011101011100110011011011111001001100010011000001001011000111010110010010000001011100110110000111111000001000101101101011000100111000101010110110001110010101000011111000011000110010011011101000011001001111001000101110111101001000101000001010110010101101110011101010000001101101000101111111011001000 1100000110100111010001100010101101100001111100111010010101001111101001101100001101010101011001010110000010111100101101010101100110000010111111110111001001010110101100010101010010110000100111100100101101011100000101011011001011101110101100100000110010001101110101110011110101100000100101101100010011100011110101001110101101001000001011000110001010011011110000001100101111000010000101010000010000111101 1111100001001100000100100110100100001100110110101101110101111110111101110001001001010110000001110101010100100111011011101011000100111000000110001111001001001001100111001110000000101000100000100001010000100011000110000100001110010110100000001011100101100000110001101011110100000100110011100001110111010100000101101001100111100101100000101001001100000110000001000101010000000111010111111011001001100000 1000001100100101001010100011101110000101010011111000101110011000110001000011111000101100011001110000010011110011001101000001010110110000101011100100001101110010100001001011010100100110001111100000110010100101111011001001000110101111110101010111101011110100001011000010000011111110101100010000001000011100011001111111100011010100000100010100001101100100111010101000011010101001000001100001001001100010 1101001100100001000111011010100000111011100001101101110001010111101011001111100010000001110110001010001101000000011000001010010100101001010111100010010011101111100111101110010010100001111111001000110100111110101111011000110110110111101001011111001110111000111111000010101111110110001111100110111101110111011011011101010110010010110100101001000001100101010011001100000001001000100100010011001010000000 0001010011100000011011010000100001111001000111111110111100100010100011000100001100111011001110100010110001111100100011001001011011011000100001101011101110101010111110000111111000000001001101110010101000001100101101100000100000100111001011000010111011111110111111110111101111011000011011000000101110010010101101101100011111101111110100010010100100001101011101110111011110010111100010110001001111011000 1100100101110111101101101001110110110100001001110101001111001010000011110000101100001101111011000001000100000111101110001000100001010010101101011110000100100000001100000010010101100010110101101000001111100000001111100100011010100000001100111101001001011011001011010011101000110010010011110000010011000110111101101111111111100111111000011011010110001011100001011011111000101000111100000001011111111101 1111101011101000100100101010111101100100111100100101100111010001110100100000000001001111001010011000011111111101001001010010111001001001011011010011011111001110000010110111100001000001110110110010110000010111010000001001011010010100000100001000010010010100001011101110110101101111100011110110110010000001100010111111100010110110010011110010111000101001010101101010111101100100010111100111111000010011 0000100111010110110101100000111101001010111100101001011011101110000110100100001010010001010101101010001101110110101100011000010111010101000000111010110001111001001000110011011110011001101100001110101000100011100110010010101000011011111011110011001110000010001101000100100100000010001010110011000111001100101111010111000101000010011001010100110110110001111010011100110001010010110011101100000101110000 0110100111111100011000011010010010000100111111111011001110101001111000100011000100110000001010010011011010010111001011011011111011010111000000001011000010101000010010010000001101011010100101011001001000110100100001111101100110111100110101101011010001001111010100010001101011011000010110101100111010111111110001000001000100000010011111011000110000111110100001111010101111000101110111010000000010110111 1011111010001001001000010011011010110100000011111011100011000100000001011011000100001111100111010110110101100011000001100111110111101000101110110111100101101010110010010100110011010110000000000001100100001101000111010001100101010011101000001011011110011110011110001010111001011101101010100000011011101100000011101110100000010110001111011001111101101010100001110011100010010101001100111110100001111100 1111100101010111100001001100111010100010011110111001100011111001100111011111101010000110100111001110000100100111011010001001001100111010010101100110011111110010111000111111101110010110000110101101111101001111110100101000100001110000110000110100001011111110101000010111001011111011110110011100000111100010101001010011101001100001100101010101111110100000100001111010010000001111000100100001111011010001 0010011000010110101001111101000010001101011001100111001000010110001000001110111110110100100010011011001111100001001001000100010101001100111111100010010001110110110011011101010111111101101110100101010110101110001100011001000110100110010100001010000001101101011101101110111100010011110100111101000110000001110001010011010101010101000011010101000111110010010000101001001000010011101101100100011110101010 0000100100010000110001010011001111100001101111010100000101100001010000111100111111101001100100110010000000010100110001101010001001010110011001100111000000000011100110010110110111000000100101100110111101010001100000011011100011010000101000100111001101000110001011110111100000011010000100010111000011010000011101110001100111100111010110101001011100110001011010110110110011010000100100110111011101110000 0111100001000010011000001110101001011110111100100000100100110100111011000010011000111010100101000000000000010111000100000011000000011000100000111110110001100111000100110110010100011111100011011110100000111110110110010111101101110100001101110011111000011011010110001101001000010011011011001000000100111110011010111010011011111001011000001110111100001001111001100010111010110111111010010000011110101011 0000000010110101000111110101100110110011101100111110111100110101111000101010011000001101010010000100001100010100010000101000110111011010010010111001110110110100110001010001011100110000010100000111110100001011010000011011010001101001111000100111110110001011001011011100001111011101001111001111000001010010010111011010101111110011100100011110110101100100001111011111001000101100111100010101000010111111 1111010101110010101000100101001010010011100011100001001101101110010110110010110110111101111100000011011101101101101001101000001000100100111111111000100001001101111111001011000100110100111000010011011100100010011110110110110110000100111001100111110010101001110010101011010011111111101110100001100000110100011001011110110010010011110000011000110010001100000111100100100001010110101010000110100111110001 0100111010001011100011101101000010011010101110011000110010101100100111010000010000000010110000010101110100011101100010011001010110110011000000000110111110000110010100001010010100010001100011111000100000111000010001010000100110100110101111110001010001110011110011001010111101000010000100100111101010011100100000100001100011011101000011111100100101110011100010000001000100110001100111111101000100100001 0000100001010001001010110011100100100000111010100000000001010101001100111010001001101111101100110000000111001000111110011111110001100011110001011010001100001100000001010011100100100110010011001111101010111100100111111001010111100011111010111010000000011000100010111011001101100100111111000001100010000100001010110010110000001001101110111011011010010011000001100010110010000101010010101001111101101111 0010101010000110001100000010010011111011111110101000100001010110110101101010110111000100001000101111001111110110010010011101110000010011110010001010111110100000011100110010010110010111011100010110110111100111111101000000110111101000000000010101110110111111001100101100110100101011101100011011100011111101110100010101100101101110111011110001011011101101011011011001100111000101100110101110100000111001 0011100100100111011110110100110011100001001010110011011110000011011111010110011000000111011100101001100001110111101101011001000000001000101011000100010101111101100010101111001101000000111010101110011110010110001101110101011100001100011010000100101011101011011011110100010001101101110110011010111010001010101100001000111010101001100100100010000010101100010111000101100111100011101101101001010000101101 0100111010011101011000011111110000001101010010101001111000000100000111000001001001111001101100110100000101100110110100111001110110101111001111000111111011001100101001001110011101101010001111000111011011100111101100110100111111010011000111110000010101111010111001010101010010111101001001010101000000001100100111101000000111111000001001100110110000110101111110110000011001100101001000011110001101100000 0010110000100011110010100010000011001100011101000010111010111001100001010001000111010110110100101010101110111010110110011110001100010101100110011110101111101101001000111010100000111000101011001111000110110101110101100000010001110011001111110010001011001011001100110111111110110001100011000100111101101101101101110111100011001000001111101010011100101111111001010010011100000111010000010110110001010001 1100000000011011011111010000110100101110100100111100111111110001000110101010010111011000001110010111101111111100101001010001000001011010000010001111001011000100000001101000010110110010000010101000001010101001101111000001101010111101011110101011001000011001001110111101101010011010011110100001000110111101100001001101100101100111110001101010101010011000000010011001010101100011100001010001100000010110 1001110000000011110000000101110101100111100001000101000001011000000011101111000011101110100000011111001110110011100110001100001111010110001101110000011010101010111001010001011110101111000111110101000010111001100011000110000011000111101101110011101110101010011001111100001110100011111101101100101001100010010011100011010101110110110001111110110011011000001000000011111100111011111000000110010110000001 0110110100111100010110001011011010000100001110100010101001110110010110011000110110101011011111010011000011010110010110010011000011111111000010001100110101001011000100010101000101000110100000111001001001111111001011010011101000110110011001011100001111100101100000001110010100111000101100100001101100100111100011011011000100001111101111001001110010110110010111111110001101110010110111010110101010010110 0111111001111000111111110100010001001010100111100001011101000101000000001101000000110100001100011101101011000010100010001011010001011001001011000111101101100001010111011101001111101101001001010111110001011101011101010011001011100111110110011101010000100111001001100100000011100101001110101111100000010011101100111001000011110111110011010111101000111011100101010111010000011101001111011001011101101001 1000010010011000100001110110111010011100100000111000001010110100001100000100001001011010000100000100100000010110001000011101100100101011110000001111101011001110010100101100111111110100010000111101100111100000111111111001010110010001001001101111101011110000100110001010011101101101001010110000001111111010100100011100101111010001111011101010110011000000101110001101011100010001010100110010010111100000 0111010000111000001010001010100111000110101100100000110011011000100010011000000001101011111001001111100011111011111010011110011011000111001010101001011101100010001101010011111110011010101101001100110000111001101000000110100101101011100100100111011101110001101110100010001101001001010100111101100000111101011001010110100110110001010111000011110110101110000010101010011110111011101000101001101011110011 0001011011000001001010101101111110100111001110100101110111111101010101010001111110010111101010111111111010111011011010111100011011110011100110100101000110101010110110101100011111101101000001100010100101011011101111110101111000000111001000101000011110001110101001001111000100011111001100001011111010001001111001001001111011011011010100110001100101111000110011100110000101000010000000001100100101001000 0100010101001010111101110110000001000000010000010011101101101101101101000100011000010110101011110110010001000100110111101001101111000110100011000001101111111011011000110000011110100000000011100111010111000110100011010101111010011011001100000111101000011011100000001110000010101111010010001110001011001011001011111011110001011100100101111000000000110001111001011001111001000001100001100101000000001100 0001010111011011001001011011110010011000001001010101111111100001110110101110001100000011110011101101110101111011100011110110110111100110100110110000110010101111010010101001001100100110101001010011010010111001110011001001000110001001111011100011101011011111001111100000100011000101000101100011010011100011000011010011010011110110110001001111000011010000101101010101100011101110110101000011110001110000 0110101100100101101100000000111000101101111101101011110100100100000111101111111111110110110010101111110010010000110010000111101111101000000110110110110110011011011101011011001110100110011100010110111001001001100000001001101111111111010101111000010100001111111011001100000010010000110100110100010000011100010110110110001000100001001011100100010011110100001001000110110100111010011000010101110001000111 0001110001000100101000111001001101010100100011001101011010010011110111010010010100001101100100010010111001010100010001101000001101110010110110011000101100010110001100000111000111000111001010110000011000000100001100110110101011101101011001010100110110000010110010111111101000011100000101111101001111001000111010101110111101000011111101000110100011111000010110101110110010010011111110101010100010001010 1110100001110101011101101110010111011110101111110011111001001110100110001001010111001000100010010000101001100000000011011000110110011001111101110100000100100110011110101011000011110100011100010101110001001100000000110000111001001101000110100110101111111001110010100011111110111001001001000010011011000000100100101110110101111111000010011101010100011000111111110001000101100000000000110111101110010110 0101111111110101010000011110001011100100100100111001010100011010110101001001000000010000101000100100101101100111111110010011001111111111100011100000000101110101001000110001010011001101110001011101010100101001100001010010101011000111001001000111001001101110110110010010110111101100100110110100101110110011011011001010110101100010110110011011100111101011110110111110011100010111011111100111000001011000 0011010010111000010000100011100110001011101011000100001001011111011000111011100101101011101011011111000001101110110101101110110010010111110010000010010101101100101010010111111011100001011101100010001011001000110011110100000010111110101001010010000000101110100101100101110100111000100110011011011100011100101100011100110010000100000100110011011011001100011100000011011110001110110010001010111011000001 0111001110100010011010000001101011010101001101000110100010110111100000110011001111001011011011001011001110010001100000000010000011101000101011001101001010010100101110110110111010011100000110011010011100110001001111011010001001110101101110110011011010010010011111001111000011101010110000100101111011110110001000101110001010001011000011101100010000100101110011000011111111100100100100001101101010100101 1101010011101110001110001011110001001010010010110111000010001000101110101101001100010000111011011001000010011110111110001010110110010101000011001011011111000101010110100011001010101101101010010100101100100000010101000110011000111100110101100011001100101110101001100111111100011010110100100110001010110110111001000010101010100100101111100100001000001000100111011110011010101010001011100100010101110101 1110101011100010011000001100011000010010011011010111010110111001100111100110010000010010011001100101010110111111111000101100010010001001110100110101100110100011101110011100011110001111100001000100000000011000010100011100101111110110111001110100001110101110101110001110010001111010110100000111110110001010110011100000011001110011011110001111111011000111000110111000110001011110000100001001000001011000 0010111101110011000000000111110011011100000100110000000011110111111001110000010101011011011101100100000011011111001100010110111110000010010100111001111001100001011101101100011111111001000010111001000100010101000000110101010011110000011101101110001111110111011101111011101101111100111111011110011111011101000000000111011100000010111101110011110100101010010100011000011110100010110010101110111110100111 1000100110011010011001100111011100110100011010110010000111000100001101111111001010010011101100000101110011111111011111100001011110110000001101110111010110100001110010111010100101100010101000101101110110111110100101100111111010001001000000011010011011001100000001110101111001111101110001110000011110001000001110110000101000010101010111101011111110111010100111110101001001101011011100011111100010011000 0001111000000011010011100001101100000111000110011111101101101010111101000111001001011010001110000001001011000100001001110100011101100111111010111101001100111110100110011010100110001000110100110100100000101111011101011101111100000000100001110101011110111110000110110101110001100001101110110100000110110010101001010001110110111111001101011010001100001010011110100010101101001001001010000111111101100111 0101010100111010010001010010100111001101011001010111110110111000101110011000001100011111111100010101001000110110010110101101001110111111101000010011000001110101110111001111101111110111001111111001010100001100001100111100111001111000000111000110100011010000000011011101001101101010111010111000001110001101010011001001001110001100111111110110111010111000011100010010000000110010011101000001100101111110 1011001000100101100010010001101011110000001011101111110100000110011100011111110000110110101110110011010011001111011100010110111001000110001010100100100011001111011010011000110110010001000111011010100100111011101110011110000000111100110011111110100011011011110100001000111101111100100010011101010110100011011101010001101011111110110010011111111010000101111000001001100101100110110101111000100001011000 1111011000010110101111101000101110111010001011101100000010010100110000010110011011000000110101011101110101101010000110100100000011110011100100011010000000101010001110100000111101101001111110001110011101010001111111001111001001100011011100100100100010101011001011001010001101001100011100111111010100100101001001101110000111100011110101001110000010111010111101000101011000011100011000001110001001111010 1100000111010101000001111100001100001100110000010000011110111000110010011100100000000011111100000101010110101111010011010000110101000101000010110011000111001011101111000111011010100100010101011111001011011001001111100111111110010110010100011101011110011111011000011110001000100110001000000100010110000100011000010011001000010101010111100100111000111100101000001010011011110000001110111100101110101101 1101111101001110100101101101001110010101110101001100011101100010000000000110110101010100000111000001110010011001001000011010010001001010110000111100011111011100111101001110000011010010000101101011110001100010000110001010100011100011000010101001100010111111111000110100011111101010000110000001111000010101100111011000111110010101100111110011101011110110011101100100011100010000001101011010101010000101 0111001011000110001111010000100101010000101000100110100011111111101001111000000000010101010000101010101001001100011011111000100001010000111010100100100010101001110100000110111001010100000001010111100010011110100000001010111001100010101001111111010111001010011011111100101010100110001001111001111101010010110110001010101100100100100111010001110111110000000001011111110001010000111100001111010001100001 1000000101011101100101110110001011101000110100110111110000010010001101011010000001100001100110010001110010100111001000101101101100110010111111101100111011101010110100011101010000101100100000111010000000000011100010011110001010110100101010000110001011101101010010011101101001010011000110111010101101001011101110011011001011111001100100111110110000110111111100110111111011100010011001000101100111100100 1010010110101110011110100000000001100111101101101010101100111010000101010100111000010011110110011100100001011111010001111100100100001011111110011000111001001001011000010111101000010000010100000011111101100111001010000111010001011110100010001010001101110010111101000101010111101000110101010000011001101001100110010001110001110010110010001000000111100011101001000010101011110000110000101000101001011010 1001110101000101011101000100011001011110111011101000010011110001001001011010011010100100011000111011011000010111001111000100111100000010101100010100110011010110100010101110110111010010110101100110000001010000010000001000000011001111110100111110011011101101100101011110101001011100000001101101111010111000110001000111100111110001100101011110110111000111011111111100101000110100011000010101111001010000 0101100100111101100001000100011110010110001100000000101100000101010010001110010011111100000110110111011101101111101011000001101011010010100100001000101101010110100101011101110000001000101111010000110011000111111000110111000111001111110101100111000111001010011010001101110110111010101101000010011011100100000001000101101110011011001100100001110100101110011111101000011001100001101000111011110110111101 1011000111111010010110101101011111011011000111101011100110111100011111010111100011000010110110010111010111001011001101001100011011101001011011011011100111001010111110110101101110011101011011000110000110100111011001011110010101100111011110110101110001100101000110001000111101110100111100111101001110110101110001001101001111001100110111001001011011111100100010000001110001010111111010001000010100011110 1001111101110100001011101001011010000111111110000101101011110111111101111011011110010101101100001010010110110001110111101000100110111001101010111111001111011111000010100110001100000111010001000001010100000101111001001000010101011110111111010100000010100110111010100101000111110000110011110010111110010100010100101001011110101110000111011100100100100111111010101101100100101010001110001001000000100001 1000010100100101011100011010110111010010001011001100110111001011010101111110100010010010010011011011110111010001100111111110101010111000111000000011110111101100110011111000001100110001011111101110111001101000010011000000101000010010011001011001111011000111000000110101110110001101111100100010001110000110010111001110000010011001001000101000001010100010100101111000100010010010101100100001110011111000 1100010010111100111110110001011000101000100111111110101110011110000100011001110010111001111101111001010111100111000000110010111000111011001101011111110111011001101000101110011011100100111111001010010100110100101001100011100110111000101010101001011110101001011000011101001100001001001011010001110001110110110110100101100111110000011011111011001000000011101001011110000100001010111111010000000101000100 1111001100111101100001001100011101000001101011000000010011001101000101100000101001001000011110101110111110101000110110100011000100000000100011011101101000000000001101100011111000001101101100101001100101100100011011111001111101101001110101001100011010101010010110100100000000000010011110010101011111110011101010101101011101111001010110010011001101110000110010111111100010010110100000101011000000100110 0011111100111001011110010010010110001001000000010011111111001000010001001011011111110011101000101001101110110110110011110000111010110100100000011000111010101111110011111111010000011101110011101010101010001100001011011001110101001101101011000010011101000001100101100101000001111001100111010000011111000011011110111000001001111001000110010101000000101010101111000011110111011100001000000101100000011100 0010001001101110010000101001111101000000101110100111111110101010001111101110110010000011111100100110000110100101110001101001101100011011111011111111010110101111111101000101101011111011010011101011001010001011000100011010011101101101011111111111101010110001100000100010111101011000111011011110001100011001011000101011101111011001110101101010011001101110100110010000001111110111111101111100001000111101 0101010101011101000110110111101100010000111110001000101101000011011011011111011011000101111000101001010011010111001100110100010011110100010110011001000100100100100001011011010100110010110010100011010001000011010101101111010100111000000101101011010000010001111110100111100001111101000010011010110110100001011000101111011000111010101011110101111111110101000001100000100011010110101011000011110110000110 0111110010100011101100111101100111000000010111011011000111110100000011101111001000110001111111011101001001101111100010001110001110011100101011001010000111001111101001010110011010100010001101010100001111001010110000010010011100100010011101000010001110010111110011001000100111000111101110000011011100011011110110011111010100011000111111100100111111011000110011110000101000001011011101101101011111011001 1110110011101001001101000000011011111001111111001010100101010110010001001111011001110000101101000101101110111111010110110111001010101001111011011100100000000101011110110101100011000110111111001111110000000000111101101010000001001011101011111011010101010000111110100100101001100110101101010111000011010010111011010000011111100111001000000001101010010000000101011110110110000001010000010001100110001110 0101110111000100101101010110001110111101010001110111101110010101001111000010001010000110011000011000101100001000001000110101100110111110011001001110100110101111100010111011101110101010110100001100010001111000111100000101000100001001011010010001111011111011111000100001111000101111010011110011111101101111001011011111010110111000011000110001100010100000100111010110011100100011010110111001111011000000 0010100100101100101001000000001001010100110100001010010110100100101110101000110111110001000001100101000001111111101010011101000111010111001001001100011011010101111001001110110111111101101111010000011011000001111010001000100100101010110011011100110001100100111010111110100011000001110010000010101101010000111111100111110100110001101111100100110001000011100010111110000001011111001010101000100100000100 1000100101101011110101100010010111101011011010011011100011101100011000111010100010111000110010110000100101000110100111011110010110100001000111000010111100000001100100110110110010100101101101110110010010110001101100000001100110110010011000100011000000100110110010010111101101110111110010101111110000011011011100011101010001110010111000110100011101110010001110111011110000101100001011000110001101001111 0001011000110000000111001001101101011011110001101111010010011111111101000011000110101101110011001001010110011111001111000110011110010001010101101110100000100100001011010000110100111111000001100010000111100111001001000010000010001111111011011010010101111111000111100100011111000010101001000110011111000101100001100011001000001001001110100001111100101000101111101100000111101010111101001010111000110011 0001100100101011000001000111001010100011101111010000011111100100011001010100001001110000101100000000000010010011111110000101111100110100010101011010011010110100110001111101000000000010111101010101001101111011011001101000010110110101111010111101111010111000100011111110000011110100100101110000111111100110111101110110101100001011100010111100010000010010001111001110100111010001010110100001011110100000 1100110010111000000001000111000101000011101001001000111010000101001101010110011100111010101000011001011111011100001110111010010000011110111010011111001110001010011010001001000001101010011100101010001000001001010101110100100101011000111001110110101000100101001110100101011110101100111000001101100100011101000011101010010100011000111001011111111100010100110000111100010110111101001011011010110101101101 0101000110101101010010111000100110000011001001011011100001010001111010010010101001111000011001000010001101101100101010110110011100010001111101111101101110110100000010110111110100111100100101100110010110110000010011111110001001101001110110101010100111111001011100011010011111010010111001100100010101010111101101100000001101111000110010101100000111010111000110001110000001010000001010000101110011001101 0000110011111100111111000011111001111000011100111101100001000011101001100111100111110000101100001111100001111101101010101011010000001011001011100010100000110100100101000000111000100001001010001001101001110111011010101110110001110001110111110110111011101000000111000101111110101011010100010101111110110111101111111001101101011111101101010000101011101100011010101111010110111000110011100101001011100011 0110101000011000010010100110010011011110011101000000101011000101011110111110010000100101101011010101111010001110110101100000010011000111001011111001111100111111010111101001001001101100100100111110001010101100100100001000001111001111101101111010001100010010010101011000011110011011101010010001001101100101100100111101100000101001000111101001010111011001001000111001010010010101100110000100110000110111 0111111000111100011110111010010100111011110000010101011101100000110111100101111111100111110011010010010110011011100100110110001000111001111110000110111001011000111111001000110100100111110101101000011111100110111001010001011110001110010001011110011110011111011110000000100101101111010111000000110010011111111001100101001001001001011100001001000111110110011100011010100011111111110100110000011010001000 1101001001010101101001111100110010111000101001010101111001111100010110010000001000000001000111101110011000101011011000110101001110110111111001001001110101001110000111101101010001111000110010101000011000011111010111000110011110011010101001000000110100000111110110101011001001010001101001000111000110011101110011001011111000001011001110011000101001000111000100011100100011100111010011011010001110011111 1110100001100011111001110010100000001000101111010000010110110111101011011000011110011011001000010001101110001011101000011010100000000110100010010110110110011000011111110010111111001000000010000110011001001101111111000001010101011110101100000100110101100110001001000100001000101100100110101101110011110100011100100100111011000011111110011111100011010101101101001000100011110001010101101011011001001110 0001011010010000100100110010010010000100111100001000010001110111010011110010010001101001111100001001010001001011001101111111000001001110000110011111010010001000010101010000011010010111000111000111001010100010001000011101110000001000100000111010001101100011100000101010111001100111011101101010111011110100100011001011001101100010111010110001110011100110000001011001100111101110111110010110101101110110 1101000110100010001010111111000011000100000100011001011101100111100110111110001101000010011001111011111100110110111000101010111010011001111111011111011100001100100000111101001101001101110001110101001100010010100101000001101110110110100011000100011000101010100000010101101001111100111100111010000100111011111011111101110110100011011100101100100000010101111011011100010110011111001000111010110111110110 0000000111000000011110000101111100110111011010111011111001110110001000001010001111001110111101010011011001111011100101011100010001101100000111000011010000110101011010110101000110111000010111101100011100101001001100001101111101011011010100100011111100110011001110110101110110110101000111110101100101101110101100110101011101010000100000010111001110011010111000010010001100111011000011101001101000100110 0010001001001111101100110100011100010000010011001111000010100101111101001001001110001100010111000110011110000000000000001001000100011000111101011010110110000010100000101010101101101100111101111011001111100011000000100011011000101000000001001100001011101001010111111011101010110111101100100111111011001111111001000111100001001111011010000011000011000101100000001011010010001010011100111100011010110100 0000110110101001110010001000000000110111111000110100101100101101101110101011001000011100011111011010100000001110101001000101101111110010100010110011001010111100001101100010010001111101111100111111110010011101010110110110110111101100101110010100101110001110001100101011110001001011011101011000001000111010101111100000011101010011011011000001011100111111101100010111000111100010110011010011101011001000 0000001100011100000011111100100101000001001101101011010100001110111111110000000010010000110101010000011000101101101001100000010100111010100100110111000010001111110100111110011101111011000110101001100001111011001011000110110010100111011000011011010100000001000001110110001100100111111101111100010110100011001010110000010001101111010011111001010110111110000111101010010110010100000010101000101011110100 1001111000100101110100000000001100111101010110001001010110101101101111100010101011100011001000011101000101111000101000111010100100001101111010100111110111110000011110101111111001111000110111011111110001110111001101011010111001011100111111101111101001011101001110001000110011010001101110000110000011001100101110010001111000000000111011000101001101101101000110011001000100111100000011011010100101000101 0001001111000010110100001111011101100101010101010100010100110010100001001111110001000111110000001100100110010010111101000001100100011011111011101110100010000010100111100110111100011010000001100101010101110100011001110101111111001011011011011000101101000101011010100000011110010000011000110000010111010111000110001010010111001011110111101100000111110000110101101101001111101100000111000010110010011110 0001101011010111110110001000101101010111011000101001111000000110011010110111011001011110011101011111011110100101110001101101010011110110000111010101001001010111000011001101101100101111001111110100001011110010010100011111100000010011100011101110110010100100011100000000101011110101101111111101100010110001011111010001110111011101011100111011010000010100011110100110000111011001111011010000010100010101 1000011000100000111010111011001011011100111001110100110111001010110011100000010111010111111111111010011100110010101010110110110100100010111011010111101011011001111111001100101000000001100001000111110010110111110010010001110110111111110101100001100111010101101101001100000000101010000100110001111001001111100110101111100101010100011110101101010001000111001000011010111000011100110011011111101110001110 0111010100100000110110001101011000100100000010111011011011101101000001100100101110010111001111101101001100000101000111101011010110111101011010000001100010010100010100100100100010111000011110100000011000001100001000000010101100101101000001110000111111011111100010101110010011111101111000001111110100110011110010001100101001100101011111101000000101110100101100011011110101001111001011001100010111110000 0010110000011101010100110110000111000001000100010111110101000001111011001101101101010101101011010100100010011110011011100101011001010010111111000100101111000101101100100111011000001001000110011010011101011100000110000100010100110000010111010111000101011010011000111101110111001101000111110010111110100100111010010101111100101000011011101100111110110111110111110010100011011110001110100010101100100001 1111110010110011010101110011010110110101011010001101101000101101011100001010000100101111010011110000101110101000001001101000111000111110111101010110110110111101001000101001111101101101010111011011001001100100100101010111011010111101101101011011101001101010110010011000111110101110001111000111001101110100100001010010100001001011100010101100001011011111111111100010100000001001101001011010111110110011 1111000110100000011110010100011110011110110000010101010011010110000111110110010010001101000010001001100111100101111100001011100011111000000111001010111111101010110111010010001111000101100001101110010010010010000110111000101000111011101011110111001011001000101011110111110111110011001001111110001101100001000010010101001111110010011010010001110100101110000001010111100111001011100111001000011110101111 0100101111011010100011011011001111101001010111011000011000010101001001110001000111001001111111110011110100111011100010001000011010110001001011010001000001010000100101110101000101111111110010011000100010101101010100010000001001011011110101001110110101010010110000100001100100101001001001111100011101111111011111010010011001101001101010100110000100010010100110110110111010111101100001000001110110011111 0110101010101010100111110001000110110001011000111100111101101011010001100011000001110101100000011100100010100011011101010111011010101100111110000010001001010111001000101100111110000000010110110010110010011111111100001110101111000101101000001001110101011010001101101000011100111111011001010110011100011011000100000111000111011101001000010000100000000111001001110001110001100110101110100000001010111001 0000010010101111010000000111101000101110100010011111010111100011111001101101010110111010111100000101101111011011011000001100011110111100000100111101110101111101011110110100100110111110011001100000111001011011111011111101101001001101001000101100110001110110101011100011101101111000000010001000001101100001100110101100100001011001111110011010110101001110000111111010110111010101111111001100000011000010
C#cTrader Algo

【cAlgo】cBot開発でも新しめのC#機能を使いたい!【Tips】

7/30/2021

4年以上前の記事です。内容が古くなっている可能性があります。

cTraderのcBot開発にはC#4.0の機能までしか使えない?

cTraderフォーラムを見てるとときどきこんな話を目にします。これはある意味正しいのですが、正確ではありません。

確かにAutomate画面から右クリックで「VisualStudioで編集」した場合、そのままではほぼC#4.0までの機能しか使えません

ただ、新しい機能を使う方法がないわけではないのです。少し詳しくみてみましょう。

 

C#の機能とは何を指すのか

「C#の機能」といってもちょっとざっくりしすぎてて何を指すのかわかりにくいので、ここでは2つに大別して考えます。

①言語自体の機能

いわゆるC#の新機能というとこっちを指すのが普通かもしれません。「こんな文法が追加され、こんな書き方がこんなことができるようになったよ!」みたいなのです。

たとえば文字列補完式。変数priceの中身を出力したいときはこんな風に書けます。

    Console.WriteLine($"価格は{price}円です。");

この文字列の中に{}で変数を埋め込むというのはC#6.0から使える機能です。

同じことをC#4.0でやろうとした場合、こんな風に書く必要があります。

    Console.WriteLine("価格は{0}円です。",price);

微妙にわかりにくくて不便。WriteLineで使うならまだいいのですが、普通に文字列生成したいときにはstring.Formatを使わなければならないため余計に面倒です。

実際(普通にやったら)cBotやIndicatorの開発では文字列補完式は使えません。これは実は使ってるC#のバージョンが低いわけではなく、C#4.0以上に相当する機能はcBot開発用拡張機能によってエラーとしてはじかれるようなのです。

逆に言えばこれら新しめの言語機能は拡張機能にさえ邪魔されなければ、コンパイルもできるし動作も問題ないといった機能なのです。

 

②.Netフレームワークの機能

例えばWeb接続なんかをしたい場合、現在だとSystem.Net.Http名前空間のクラスを使うのが一般的だと思いますが、cBot開発においては(そのままでは)使えません。

using System.Net.Httpと冒頭に書いてもエラーになりますし、参照追加しようとしても選択肢に出てこないのです。

「C#4.0までの機能しか使えないから仕方ない」とあきらめるのは早いです。これはC#の機能ではなくて.Net Frameworkの機能でして、.Net Frameworkのバージョンが古いのが問題なのです。

cBot開発時のターゲットフレームワークはデフォルトは.Net Frammework4 Client Profileですが、System.Net.Http名前空間は.Net Framework4.5で追加されたものなので使えないというだけです。

ターゲットフレームワークさえ変えられれば利用できる機能ということです。

 

フレームワーク依存の機能だけでも使えるようにする

先に簡単な②を解決する方法を紹介します。一応簡単にフレームワークの説明しますが、方法だけ知りたい方はこちらへ。

 

そもそもフレームワークってなんだ?

C#やVBといった言語は.Netのフレームワーク上で動きます。要は.NetのフレームワークというのはC#やVBを動かすために必要な基盤です。JAVAのプログラムを動かすためにJAVA仮想マシンが必要なのと同じように、VBやC#のプログラムを動かすには.Netのフレームワークが必要なのです。

例えばcTraderの場合は.Net Framework 4.0上で動くため、.Net Frameworkのバージョン4.0以上がPCにインストールされていないとcTrader自体動きません

「そんなもんインストールした覚えがないぞ!」という方もご心配なく。.Net FrameworkはWindowsのインストール時に一緒にインストールされています。Windowsのバージョンによってインストールされてる.Net Frameworkのバージョンも異なります。

この.Net Frameworkが色々な機能をもったクラスを提供してくれるおかげで、C#のプログラムではネットに接続したりみたいな実際は複雑な処理が必要なことが、たった数行のコードを書くだけで手軽にできるわけです。

(なお、今では.Net Framework自体がすでに古いフレームワークです。.Net Frameworkはバージョン4.8で更新が終了しており、現在はWindowsのみならずMacやLinuxでも利用できる.Net Coreが主流となっています。)

 

C#と.NetFrameworkの関係

C#のバージョンと.Net Frameworkのバージョンというのは確かに密接な関係にはあります。例えばC#4.0であれば対応する.Net Frameworkは4.0です。

(それぞれバージョンの対応はQiitaのこのページが参考になります。必ずしも同じ番号が振られてるわけではありません。)

こういうと、「C#4.0機能しか使えないのだから.Net Frameworkも4.0までしか使えないのは仕方ない」と思ってしまいそうですが、そういうことではありません。

あくまでC#4.0の機能が.Net Framework4.0までの機能をベースに設計されているというだけの話です。C#4.0の機能の中には.Net Frameworkが4.0以上じゃないと動かないのもあるよ、ってことです。

 

ターゲットフレームワークは変更できる

cBot開発で一見.Net Framework4.0までの機能しか使えないのは、ターゲットフレームワークが最初からそう設定されてるからというだけです。

別にcTraderが.Net Framework4.0で開発されていたからといって、新しい.Net Frameworkさえ用意できる環境であれば、cBotやインジケーターまでcTrader本体に合わせる必要はありません。

cTraderのcBotやインジケーターを作る場合、ターゲットフレームワークとしてはデフォルトで「.Net Framework 4 Client Profile」が指定されていますが、そもそも今cTraderが動いてるPCで.Net Framework 4 ClientProfileしか入ってないなんてことはそうそうありません

少なくともWindows10であれば必ず.Net Framework4.6以上が入ってます。ターゲットフレームワークは新しいものに変更してしまいましょう。(自分が使うだけのcBotやインジなら選択肢に出てくる一番新しいものにして大丈夫です。)

VisualStudioの「プロジェクト」メニューの一番下、「 (プロジェクト名) のプロパティ」を開いて、「対象のフレームワーク」を変更します。

これだけで「〇〇というクラスが使えない」「〇〇が参照に追加できない」といった問題は解決することが多いです。

 

 

C#言語機能の新しいものも使う方法

次に①の新しめのC#言語機能を使う方法。要はcBotの拡張機能が邪魔なだけなので、拡張機能が動いてないところでcBotを作ってしまえばいいのです。

 

C#の新しい機能使いたいなら、メイン処理は別ライブラリとして作るべし

結論としてはこれだけなんですけどね。ライブラリを作る際はターゲットフレームワークは自分で指定するため、これもできるだけ新しいの選んでおきましょう。

これによりC#7.0までの機能はすべて使うことができます。以下で手順を詳しく説明します。

 

手順

ライブラリとして作っても、cTraderで使えないと意味がありません。ライブラリの機能をcBotやインジケーター本体のalgoファイルから呼び出す必要があります。

そのため、こんな手順で作っていきます。(cBotで説明しますが、インジケーターでもRobotクラスがIndicatorクラスに変わるだけで、ほぼ同じです。)

①ライブラリ側でRobotクラスをメンバに持つMyTestLogicクラスを作る。

②ライブラリ側でロジックを実装する。

③algoファイルからはライブラリを読み込み、MyTestLogicオブジェクトを作り、メソッドを呼び出すだけ。

では一つずつ見てみましょう

 

①ライブラリ側を作る

VisualStudioで新規プロジェクトを作成します。

新しいプロジェクトの作成で「クラスライブラリ(.Net Framework)」を選んでください。

次の画面で名前やターゲットフレームワークを設定します。

名前はなんでもいいです。フレームワークは自分で使うだけであれば、一番新しいものを選んでおけば、上記②の機能も問題なく使えます。(デフォルトで新しいものが選ばれてると思います。)

あとでcBot本体から参照するときに作成した「場所」が必要になりますので覚えておいてください。そのままであれば自分のフォルダのsource\reposの中だと思います。

続いて、cAlgoのクラスを使えるようにcTrader APIのDLLを読み込みます

ソリューションエクスプローラの参照を右クリックしてして、「参照の追加」。cAlgoAPI.dllファイルを探して、追加します。おそらく PC>ドキュメント>cAlgo>APIにあります。

あとは冒頭にusing文を追記すれば

using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;

これで、cBotを作っている時と同じ感覚でcAlgoのクラスが使えるようになります。

あとはClass1の名前をMyTestLogicとでも変更して、こんな感じの雛形を作ります。パラメータを持つcBotの場合は、コンストラクタの引数にでも追加しておいてください。(インジケーターの場合はOutput属性のIndicatorDataSeriesも)

namespace MyLogic {
    public class MyTestLogic {
        // --- フィールドにrobotを持たせる
        private Robot _robot;

        // --- パラメータがあればこんな感じで
        //public int Period { get; set; }

        // --- コーディングしやすいようにプロパティ化しておく
        public Chart Chart => _robot.Chart;
        public Bars Bars => _robot.Bars;
        public double Bid => _robot.Bid;
        public double Ask => _robot.Ask;
        public Symbol Symbol => _robot.Symbol;
        public string SymbolName => _robot.SymbolName;
        public Positions Positions => _robot.Positions;
        public PendingOrders PendingOrders => _robot.PendingOrders;
        public DateTime Time => _robot.Time;
        public History History => _robot.History;
        public MarketData MarketData => _robot.MarketData;
        public IIndicatorsAccessor Indicators => _robot.Indicators;
        public void Print(string msg, params object[] parameters) => _robot.Print(msg, parameters);
        public void Print(params object[] parameters) => _robot.Print(parameters);
        public void Print(object value) => _robot.Print(value);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label, double? stopLossPips, double? takeProfitPips)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label, stopLossPips, takeProfitPips);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label, double? stopLossPips, double? takeProfitPips, string comment)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label, stopLossPips, takeProfitPips, comment);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label, double? stopLossPips, double? takeProfitPips, string comment, bool hasTrailingStop)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label, stopLossPips, takeProfitPips, comment, hasTrailingStop);

        public MyTestLogic(Robot robot) {
            _robot = robot;
            // --- パラメータがあれば引数で受け取ってセットしておく
            // Period = period;
        }

        //------------------------------------------------
        // 下記をそれぞれ本体の同名メソッド内で呼び出す
        //------------------------------------------------
        public void OnStart() {
        }
        public void OnTick() {
        }
        public void OnBar() {
        }
        public void OnStop() {
        }
    }
}

Robotクラスのプロパティやパラメータはほとんどpublicなので_robot.の形でアクセス可能ですが、いちいち書くのが面倒なので直接呼び出せるようにプロパティ化しておきます。

Robotのpublicメソッドも、PrintやExecuteMarketOrderなど頻繁に使うものは直接呼び出せるようにしておくと便利です。(他にも必要なものあれば加えてください。)

 

②ライブラリ側でロジックを実装する

中身を好きに作ります。ここはいつもと全く同じ。上記のOn~にロジックを書くだけです。必要なら別メソッドや別クラスも自由に作ってください。

一通りプロパティやメソッドを用意しておけば、普段cBotを作ってるときとほぼ同じ感覚でコーディングできると思います。

動作確認がてらこんなコードを書いてみました。毎ティックスプレッドをログに出力するという特に意味のないcBotです。

    public void OnStart() {
        Print($"{SymbolName}のチャートで開始しました。");
    }
    public void OnTick() {
        Print($"スプレッド現在値{(Ask - Bid) / Symbol.PipSize:f1}pips");
    }
    public void OnBar() {
        Print($"{Time}:ローソク足が更新されました");
    }
    public void OnStop() {
        Print("停止しました");
    }

ここまでできたらCtrl+Shift+Bを押してビルドしてライブラリ側は完成です。

 

③本体(algoファイル)を作って呼び出す

algoファイルを新しく作成します。MyLogicMainとでもしておきましょうか。

作成したらVisualStudioで開いて、参照に今作ったライブラリを追加します。

上記ライブラリを作った場所を開いて、MyLogic\bin\debugの中にMyLogic.dllがあると思うのでそれを参照します。

今回はこれだけでも動くのですが、あとあとのことを考えるとターゲットフレームワークも変更してライブラリ側に合わせておく方がいいでしょう。(上記参照

あとは簡単、using MyLogicを冒頭で宣言して、本体側でMyTestLogicオブジェクト作って、各所でメソッド呼び出してあげるだけです。

using cAlgo.API;
using MyLogic;

namespace cAlgo.Robots {
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MyLogicMain : Robot {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        MyTestLogic _logic;

        protected override void OnStart() {
            _logic = new MyTestLogic(this);
            _logic.OnStart();
        }

        protected override void OnTick() {
            _logic.OnTick();
        }

        protected override void OnBar() {
            _logic.OnBar();
        }

        protected override void OnStop() {
            _logic.OnStop();
        }
    }
}

上記の通り進めているのであれば、algoファイルの方はこれをコピペでいけるはずです。

基本こっちのファイルはパラメータを追加するときくらいしかいじることはありません。ここまでできたら閉じてしまっていいです。

注意点としては、ライブラリ側を変更してビルドしたら、本体(algoファイル)もビルドしないと変更が反映されません

面倒に感じるかもしれませんが、本体(algoファイル)側のビルドはcTrader内のボタン一つで済むため、大した手間ではありません。。

 

お試しあれ

最初だけ少し面倒ですが、簡単なcBotやインジケーターならともかく大掛かりなものを作るときはこの方法を使った方が結果的に効率は上がります

もしこの丸投げ型を頻繁に使うのであればライブラリ側のひな形をもう少し作り込んでおいた方がいいかもしれませんね。この辺はまた気が向いたら別で投稿します。

 


まだコメントはありません

新しいコメント

コメントは承認後に公開されます。承認まで次のコメントは投稿できません。

cTrader's Life

© 2025 ajinori