1001000100000110110111101111111011101100110011011010000001101001000101010010111101000011110011101100011000111011000111010000001000000111111111011111100101110110011001110101010111110001010101000001010011000101010110001010110110100100001110010110010011000111101111100001011000101000110000001000001000010100110000000010011001111111101011011001111111100100011011010011111011110101110111111000100001001101 1100001100111101011010100101010010100010101110101011000111010100101011100011001010000010000001101000110000000111001010001001110100011010001011000110000100001111111110111100010101000010000001000111111001100101101010000000111101101000100101011100010010100101101101101000110010110101101000011111010011000010111110111011110101101101000101100011011010001111111111011000011100010110011111110110110000101110 0100000001000111010111011010101011011101111001011011011100110011101111111100101010011011011000101100111010000101100100011010110001010010110100010010010100101010000000001100001101001111110000100001000010110011001000001000110011001111011001011100111011101110001011001011000011011010110110110100100110011000000101110000110011110111111011000110110010100100101100011011110010110100100010101000110101010110 0011111010000101101011010110110101000011101101011010010110100000110101011111011100111110010001110101111110011000011001010010001110010000110001101111011011101111110001100110100000001001001000101111111000000011011001100100100111010011101110101101110011011111000000011010010010110110111000110011000000001100001001110111100001110111010111111100101100010110111111010001111111111100010000100101010000100111 1101101011011000001100010111001111000000111000000010100111000111111011010100010001101100001111011010011110110001010100000101110100000101111000011010100101000010111111101001101101010011101011111011010010111110100001110011011001011001001011101110011001010101111011110110001011111010001101011111101111000000111000000010001101100111101000111111101100110100000010101010011111110101111110001110011000101100 1110100010010010011111100111100010010011011000110101011001010110110101111001111111001011110010001001101000001100011110010111011000010001001011110111101000100100110000100001111001001000011000101001001011001001100111101000010000000100111000001011110110111110010111011110111111010011000011010001011011101000111000000101110011110001110100101100011111010011010011100000110100011000111001110000101000001011 0000001001111000110000010011110100110111111010000101000010000110101011011001101110101101000000001111000010001100110011010110101010110001010110100111101001011100111111110100000111011111110010000110101001011011001100011011001111111011001111010011011000001000010100111001100111101110111100101011011011000101110011010110001011010011111100100100010110001110001010000100010010011010010011101111000111000010 1111111100000010110110101011001111001010011010001011100000010000111100111011111000111100111111111000011111001011100011011101110001010111110010011111111011100100000000100010101101000100100100001100111101110111111011110100100101110110010110001000111010110111000111110001011001100010001011000000111110101100111001011001001000110111001101101010100111001001000011100000001001110001101001000010001101000110 1001110110010111100101111101001011111110000010101011111000001101011000111011110001010110001100110000100001110010101001111000100010011101011110100110001111010010111000111110100101011001001001000010111101001101001100001111010110111001010001001000000011110100111111000101100100101011110011001110100011101011111101110001111110110000010010101000011111110100111000111100010101110110100010110001101110010001 0011011101111100101100010111010010000110111111011001101001111111001101101101111010000100111111101011010110001001000010101101100010000000110011101010000011000100000101100000011010110100110110101110101000111101111100110011001001011110101111011101110010111001010110100000011000010101111100111110111011111101101001111110101010011011000010011111100111110100011110101110111110001001001001101010010001000001 0010100101101010101011110000100000000010011010000110110110011100001000100000010111000000110111111111001001100011011000101110101100011011001010111011000011100000110110111000010111110111010100011001000000001101101000010100001110011001000000101010010101000110111111011101111100000101001100000001000011110011111010000011001110000110011110101111100111001110101110011011101100100011110110111111000011001110 1101010011001001111101011100010101000001100110100111000111011000100111000000000001101011110010000011111101111010110101011000011111000011000001001011110011111001111111110010111010000110111111001100101000100010111001011001111111011110000001010101010101011011101010000010101111001001000010111001000100011100101111110010110100111101011011101111111010100011011000101111111100001011001001111010111101001001 1011011111100010101111000000111001101111100000011110010011010101001111101101000001111100100101011111101111000000110110111010100100001010000011001001011100010001111010110100011110001101110001110100011110101100111000100000101101100111000010110111001100010100000010000011101010100000001100110110111011111010101100100110001011100110010110001110110001000011101010000111000101011111011110001100111111011111 0101110011111011111011111100101010011000100110111101101111010011000010100001011101110001111001000100110010001110010111000101000000101001010111100011111110000000011010111000001011001111100000001101010010111100000110101000010000101110111101000110111010001100000110010110001010110110010101101001101101011100100000111110011011101111111101000110001100100000010111111110111110110011101010011000101111111000 1110111001011010011010000110000011001000001011000000001100101100011010001110100000101100100010100101000001011101010110001100101011011001101010111110010111111110101010011011101100111000111110110011010001001000011100001101000110100001001110010100101000110110111101010110010111001110111010001110101011010101110011001101000011101100101001001110000011110011111100111110101111001011110111001001101101100011 0110001110011011001001110111011001110000110101010110010100000011110011111010010011001010100111001001110111100010100100001001000001011100010000010010110011100001000001010010000111001001100100111110011011000011011001011010010010111110010000011111000011011000001100001001011101000111001110001100010001000111110010000111010111011001010110000110011111111101001100010000011010111001101001011000010000101100 0010100001011100111110001010101101010010101001011100111111110111001100011000100101010011000011001000010110101100100110101110011000100011001110110101010010111010110010011111100001010100101001101101100110010110001000011101011000100010100101010100110000101001100000100100100010000101100011000100101000101101100010001111001101110000011000010001101101001101001011011000101011100110101011101001100001111010 1101000101111000001001100110101100110101010100001111100000110000111101101001111100011100011101110010000011111111100111110100011101110001100111111000010010101001101000000110110010011001101110010001001110111100111010101110001000110000100000001001000001011001100101001111111010110000111110101011100000010111010110101011100111100101011111101101100101111111000101101110111110101001101001010000011011111000 0100101100001110111000010111011000010010110110010101100000111100011101001001011110010000010110101111111100111100000100101101101010110110011100011010010000000000100011100011100101001100111001000010101110001100001111101011110110111111111101100100001101011000011001000001110001111001110000011001100011110001110001111001110101001111100111101010100100111000110011001011001011111101100000000001110111110100 1111001101001110010111011011011101100100110000110001001101101111001000101111011010101000101111101101100001110100100000111110100011111100011000001000111001101101111100000010110101000011101111000110100100011100011110100011001010100111100100101110011000000110011011000001111011001001010101100111100100001100100111000100110000111011101110101111110000100101010011001110111000010111001011001001010101111001 0011111011000110000110001001100101010010110001010111011010110001110011110001110010011011001000101100000111100011111010100100111011011000111111111001010110101001011111100000100000011111101001010111110010000110011100101011100111100100110101100101100011011111011001110111011010011111011011011100110100111111010010000111101110101010010101100010110111101111001101000101010101011010100010001001000010000100 1101001000010110111011111100011100010000111010011000011101101001011111110011100001101110110111101010011001011011010011000010001011110110000011000111011011110001100001101111111010001010010110110100110110011111001110011001100101110011010100010001100011110100101110100101110111000000000111100010010101000110000000001010110110000011100111110000110110100111111000010001101101110000011100000100000101110010 1101001000010110110011010010011011101110111011010010000110110111010111000100110111101011000010010111111000101001011111110000010100111110000101110100110110101011001010101011011001000010101010111100010110111000101011110000011101011000111110101101000000000100111111111000010110011000001011001001000010000000101100011010110011101011110100100010000001101000100010001111111010000110111110101110000101011110 1011010100110110001111101001000100011000010010010010111001100000000011111101000010011011101000111011011011100100001010001000111001010101001001011000000010110111001101110110010110101000000111001011011110101000011001011111010101000110010101111101001010110111111000001000100011001000001111110010010010110000100110000010010010000011011010011100111001010111011111101110111011000011000110011101000011100100 1110011110110011001000111111110001000110001110100110001101000011101110010001101101001100011000001111111111110000111100000001110110000011100011011110101011111101101001100111110101110111001010101100000101000001000111101100110010000100000101001010011001100000110110010110001111101010111111010111101010010011110100101110011001111011011000000001001010010001001111010011111111101101011100000010000100001000 0110101110011101100110110101011001010010111001011001111111110010000110100101001100110100000001000101001001001110000100010111110010001010011010000011101111011111010000000011010011001110100000111111000100001101111110000110001000111100011100100011011110001111001001011011111000001010110010010001110110101101100110000011110110010111000100000000101111000101110011111111110010111011110110001110000000100111 1110010111011000010110111010001110001011011100100100110100111111110110110100000111111111011101011011011011000110100001111111110110010100011111010000100010001011010111110011001011110100010001010000001100001011011101101010100001100100101011000011100011111100100111010101001001001000111010100001100010101101011100111111000010100100011000101111110001011100111100100001010110011011010100001010001011010011 1101101000101001111100000111110111110101110011111110010101010000110111001000001010101000001010100001110001101010010011001110100001100111011100001001010100111001111001110000100111011000010000000010000100111101110111010000000101100001111100011001010010010111010111101110101000000001010110001001100110010011100000010110001011010111001010000000001101000110001011010011111011111101100101001010110001010100 0111011011001010111011010110001110000100011110011010110110110110000001010100011111111001111011011111011101001000100000111100011010001001010011101001001100001110101001100111001011101100111000011110111001000010011011101110100001000101111111001011001110011111011010000010110100100110001110110000011110010111100111011110000001001011001011111010001111110010001011100000111110100011011000001100000110001101 1001111111101101011011011000101001011000110110110111001100000000011010110001001111110010000101010100011100111010100000011011001010001011101011011010110011100110101100101101111011100011010110011100110101100011000001001011001010100010111111100101001001000111100000111101111110000100111000011011000111001111110101000001111001110010110000001000110111010110101001001000011100111111011111010100101010010001 0011110111000110101110100011110100101101110010110000010111011101110101101010111011001000111100000000110100110011001011001111011111101101000001101001100001011111101010100111110110001111001111111011101101011010001101010001101010101011111001100001110011100001110000011010010010110110011111000010010100110100000101001100010000110100111101010001110000101000000101010000000110011001101100111101111110110111 0001001101110000110010000110011110010010000011101110100110110011010010110011100111111101100100110011101000001011010111111001100101010011110111101010011011111001000110001111001010101101110010011010110110110111100110100010100010110100110100100000010100101010011100000010110110101010000111010101001000101100100011000000000000001011011101001111000101100100110100100100010001101110001010101111101100000001 1011010100100011001000010011001000110010101100001011010110111101011010110110001110101000100000000110101000010101101100010011111110101010111110100101001010111010100111010111100100010101011000011000001111011011000100100100011010001010110101100100110001011101011001100101111010101101100110101001010001101110011110011010100010100111000011111011000011001001111010101010001000111111100000110110001100001001 1110100111111001100010111011000010100000101101111001101001000010100010000010010101011111111011010010001100011100001101101100101010100110100111110011010010010001011000110101000000000010010011111101111111001101001000101100011000110001011011010000001100010110101100101101110001010110110101101010001001110001111000111001111000111010010000001101101010010011011110000000011110010001101011110001110111010111 0011000001001011101001011010110101101110111110010100110110001011000100110100010110101101111111100111011010100111100010110110101101111001011001110001110001010110001001110011101111011000100100110110001011001000001101110110100110011000000110000111101100101001010111011110010101101100010100001110000101010001111111111001000101110001100111100011000001011001111000001111111010001101011110000011000010001110 1001100110011011011001001111111000110110100101000000110100011110011101100011010011011110010000110001001010100011000111000110010100010001100001011001011011101110010010101001011111001001101001101010111111111010101110100111000011110110101001000000010110100000011011010101011010010100010101001101010101100011100010101111101000111000110010010111101100101110110011010001111110110001000101110111100010110001 1001001100001001001011010111111111010011101100100011011011100001000110001110000100011000000111000110110100011011101001111110011001101001011110110110001001100111010100001010111000110100010010000111011011101001110000101110000110000000110111000110011011100001100100111000111011111011010110101011111010000010000101111111111111010110111001101101010010100001101010101101100100001110010110110000111010100100 0110001000001110101100110000010111001000000010001011000101010110010011001000101111001000101000100100110011100111001111001110010001110101000000011111000010100111101100000000000001000100011001101101111011000101100011000100111101001100011110010010001010011010000010111110101100100110000000001100010101010100111010110110101000000111011000100011001100101010001010110000101001111011110011110110110111111010 0110111000100101010000110110110010101100011110110100110001100001110110111001000011111100011000011000010000010101010111110100011011101001111110111001111011000100111000011100101101101110111011110011100001010111100011011001001001000111100011000001011111010010111001111110001100110111010011001100101000111111010101101011110011011010101000110001111100000000000111100000011110001000110101001010111010111000 1010100001110111110011100010011101001011000100101111111010100010010001001001010011011110000110100011101111100110110110011100110101101110101111101110010001011010110111000010010101110111111010110110101101100000011111000000101000010100101001101000011001110101000000001100110101100010101010000000000001011010001000010001010111000000100100001000001100111011100100100011011010111111011101111011111000100000 1101101100110100100000110000010011100001111110010000000001000101110000101001111101010101010011001110011010000011010111001100101011101111000101010100101111110110000100010010110110110110000000011011101111011100000101011111100000101011011101001000101111010001110011110100001101100100011100100111011010100011000000110100011100011011010101011000111110110010100111010101011111000001000010101010001001101100 0001110101001111000011000001111011011111010000010100110100000110100101001110100011000101101010110000011101010110101110101101101011111010101000010100111010100000010010110111111100011101000001100110011100100110100011010110000001010100011011110110111111110110111010011100001000101100110110001111011000000011011110101010100111011011011111100101110101111101000001011111010000010010110010100011100101110000 0111111010101010110001001100011000000110110111000000101010001010101101100011111011011111011011110100000111000011011000110001100010111101011001011010010101100111100101110001100000000010001110100001100110001011110010110101100011110001000100001100110110011101001100001111010010111100111101111000001100011110001110111011111101000101000101010101110111001111100111000011100001100011000011001100001001111011 1011010101101001011100010001111010010110000010010110100100110001001101011010101001111001010110101011010100001100110101111111011101011111011110010101001011111110110001011101110111110011000111101110011111000110111011001011001010001110011001110011000111111001100110010001101010011010110011011001000000110000011111111100011110110001001101100001101010100111101110010101000011011111001011001111010001000100 0010110010110011100000010100001001111000100101011010000000001110000101011011011101111001010101011111011101100111011011100010101011011010001000001001001111000011010001110010011001000001100011100001110011001000011001000101100010011000111010100110110100111010110100100001100101011001100101001111100101001110000100101111001011000100001001111010100110001110010111010010111111011110010010101110110000001100 1111110000000000010000100101101010100100001111111110100000111011111100000100010000111100110101100101000101100111111110000100111000101111111100111111011000011001011001100001101001101001000100001000110010000111010011000001101000001110101011010110001101110011010111101011001001001011111011111001100001011111011110110101111110010110010100010110011001111110010101101000000010101010111101111100001111111101 1101001110100100010001110100001010101101111001010000100101110111110011100010000101001001101011010111000001111010011110000000010111110011000100011111011011001000010110101000100101100010010000110110000011010101101000000000010010011110101100100111001011000011110000010101000011011110110001010101100101000100101011001101000110101011011011110001110111101101101110101100001100010001011100011111110010101111 0111101010001101011110001000110011101010011111111111000001101101011001111010000001011010001110111010111111100000011000111011111000000010011101000010010011101111000101011001000001100010011110011000001101010010001110001110001101000110100110010010011011111001000101011111000001101001100001001100011101101110101100101011101000101110101110111110010110001011001101011110101011110011001110110100001011001000 0000110010011000010111010101011000000011000011101001010000110111010100010101010000001110000111110111000010011000010011100100001100010010110101001101110111100000101000011010111000011000000101010010010000001000111011010010101000001111011111010111001011010001011101100000101010000011000111110110100001101011010010011010110011110010010001100001010001111100011011101110111100001111001010011011011010000001 1010110110001010111010011100101000101111000110100100000100000110110110100001111001001011000100000101111011010100010100001010111001000101110010001010000000011111011000111100101101101100010010010111101011110110011111100010001000010100101111001101110110001111111101111111100010001111110110001110000101001110011101011010100110111100000010101001100011101100010100010101001010000101101001000101010111001001 1111001111000011100011111001100100110010011011011000110000000100110100101011000100101100011000100100000111010001100011001100001111101000011010100111111001010011011100101010000110010001001101101010110110110110110100100000101011100100011110111010100010010101011101011110100010111101000010111100010011011001101000110110000010111100111000001010101010111110010010100001000000000110111101000110110001001111 0101101011100101011111011111011101101010111110101101101111010000001111100100111110100011000100011101100100111010010010111001011001101011101010001101011101010001010001101101100011101000010010001100001111010010010110011100000000010001100110100101011110100111100000010011010111111001010101101111010100110101110001111100011110001000010101000010101000000111110000011000011101000001001111001110101000000001 0101110101011100111110000110100011000111101011100100101011101111100111011111111000111000110010110100110101101011111111110101011000101001000101100101110000000001101100011111110000111010111010010111100111001111111001110001000101110000000000110100111110111110110111001010010101011001100000100110011101010110100111111101001000010011011111000001100000110111010001000110100011011011111110010010101010100001 0111111101000000011110111000010000110111010010011001010101000110100001010111100001011100011000001110101011011101101011111111001110011011001000010001101011010011010101011101001110110101000001010010101001011001011001100000000110000010110010000000111110110010101101011100001000010010111010011100101110001100101101001010010101000110101000000001101000110000100110000000010001000010110001110011101100000110 0110000100000010001001011000001010101000111111101001100010100011000010110001011110110101010111100111010001000011011000010010011101010111010011011100010100101010110010000101101100011000000001111110000111010001000000010100101100001101001010100110111111001111111001100010100010111001101101011000000110100101100101100000010101011111100101111000111000100100110110000000110000010101111001000010101011110101 0000011000110100001000100101111110110000000111110001101001000010000010101101010000100110101001101100000001000010101011111010000111100101110001000100000001011101110011011111010010001010000010110001010111001111110011001111100100010000011110111100001001010011001001100101000111100110001001100000101111110100110001100011100011110111100000000110010100110110010111101000110110101001010111111111110001001011 0110000100100001111000001110101011001011011011111110010000000001001011101010101101001101100101001111100110110111010100011001101000110010011111001000010100010100001101010010110011001010011001101110001011101001000011110001010010100000000010001010101110011101110001111111011110100001011000110110000000111110111110100111111010101000111111110011000000010001011110010101011010001010110110000101101001111010 1100111011011110110001001101000111100010101010000011111001000000111000010011011001101010000110110100100111010110100111011101010101001111100110011100011110100000111011111000001011001110011101100011110100101101110110100001111000000100011100010001010010101000000100110000011000010000111111010011110100111101101010010001011011011100011111110111000011001010000011011011110101011011011110000111000110100000 0100101011101001110011011001011000000111000101100110001000001011000011111110101101010000000101100000011001101111110101100010001011011001111100001011111011111000101101011000011101000110010101101100111010010011100111111101001000011101111101100000101011101011010101010110101111011010011111101000100111110000001001111100101011110100110110110101111000100000010011010011101010110001101011000100011110010001 1110010101110110110001010011000101100010001010100110011010100010100110001011001101101010110111111110011101101011101010101101100001010101010010000010011011101100100000011100110101101101001110101111100100010110001111001001001010011000110000101000101000000001001010011111011110110000110001000111111001100110100101001001100011010011011000011010010011100100100100010100010100111100001101101100101000100011 0111011111010110001110011011010110110110010001111110111011110100000001001010001110111101100110100010011111010000100110100111100111010110111000101011011100001100111010100011001110011100110100001101101010001101011011010011100110010111100011000110010010100101011110001111001000011000110001001110110101001000111011100000101011101010101010000101111011110010110111101011001010000101000011101001111011000001 1010100101110111100010000010111010111100111110111011001110001011001111011110110101010010000110010001010001011001001100110101101101111000011110101000100100001100100100000000100011001001110100001111101100100001001110010011010100011101001110011111110110100101111100010100100000110011000000000010011001001100110001110000000010111111011001011101001111100011110100101001010011100110010001001011101001001100 0100101010000111001101101101111001100110111011011010000111111000010100100000001111111111011001001111001001011010011000101101100010100000111000000101011110000011111000101010000110011000100100111011001111001100001011010011100010110101110100001110001010100011100111101010000101111110011010010000001111011111101100001101000001011110010110011001011010000001010100110000011100010101100101111110010010100011 1010001000100111100100100111000110011111111010111110100000111111111101110101000100100111110011001010111101110001000110000001010010000100001101010001100000100000001111000101101101111110100111011001101000011001011011010100101111100011100100111001001110011000101001111011000001011111011110101111110100011011110110001001111011101110101110010000111000011011010111110100101101111000000101011001110111011011 0111000000110111000001001100011111101000011100001110101111101000010011011100010011101000110010001110101110110111000010001010101111111011111011001100100011001110110111011011100110101000000000000101011111101111010111010011001001001101011011111010111101100010100000101001011001100001111100100101010100011001111100110111000111011000110011111100011100011010110100011101011111000010101101000010111100010000 0110001001100101001001011000101110000101101001001111110011100001111110110111010011100011100001100111101100101101010111111101010111101011101100110001011010010110111110011010100110001100110101100100111000011000111111100001111001011100011010100101110101010001001001001100110010010001010001000101010111010010000000011010100111001100111100111110111110000001100100100100100000011110101111011111100101010100 1111100000001010100101001100000101111000011101010111111001101101111001000000101101000100101100000111101101100100001001110011100111100111011001111101010100111001011110010010010000010001010011010010001011011111010001101101101101011011011010001001010010010001010111011110100101111010010001100111001110011100001010111010101001100011110010100001110000000111110010001111101100100000101010000111111001011011 1010101001100010000100111100011001110011010101000000111000110111101010011001101001101110011001101101111011011011001111001101110110010100001010110001101100100111011100101101011010110110011110011010010010010100000001011101000110111001111011000101111100100101011011101000010000000110100010010110010000001100111000110101011101010010101011000100110000111111001110011111001110101000000001111010010000100000 0110000111010110110111101000011110010110010100101010001011010001101111010011010110111001011011110001010110001100001001001001101100000111000001011101000110011001110011000011111110000100110101111111011001011101100011100011110110001001111110111101100110100101101011000110011111011001110000111101001100111010000110100001001101001111010011010111011101100010001000000100100011001100011000010111111001110110 0100010110111000001100101011111101001110001011011110100000110001101011010010000100011000100100010000011100101111111010110100100010010000011001101001111011000100101001011100101011110110111010110111100110010110100001000110010010001110111011111110100001011001110001101111000011011011011100000010000001000010111101101111010101001110010000111100001101010110100001000101100110011011010101110111101111011111 1111000100001111011001100011110100101100010100110011000101100001011101101101101100100011011010110100010001010100001101100001101100010001001011001110101000101100110011111000001000011010011000111111010110101011010010110101011100110011000111011101111010101100010111110100011100011011111001111101101000101110101011001101011100010111000001001010011101010101010111101011000111000111110111011001011110110011 0100011101010111110100000000001101101111110001011100000011111110101100000111110010001001100001110110001100000011010110011010000001110010000110001011100000111010110001101000100001111000011100100111110001100001110110100001001101111011011101001110011001011100011101101000111010010110000001110110000011010000011111001101111001111010100010111001100111000100001000000111010010101111111001010111100001110001 1010010110110001100100101000000000011000100011100100010100110111000110101100101101001101010101100010110110001110000011001100101001010111000001100101100011101101110011111101000011101110000010100011111110011011101101111000100110010101111001101001011101101000100001100010100000011001000110010100011100001011010111110001111010111001001100111001111011110011000110011110100101111001101011001011000011011011 0000110100110010111001011101001010100010111011110011010000010001001001000111010111001110110101010011011011011110101111010000111100100100100011000000110111100100101110000111011111010011010010111001010011101001010010100101010010100101100100100011001011010101111101000100110101100111110000001100001101101101110100100110101011110001011110010010111000001100101000001001110110110011001101111010111110110001 1110101001100100000111010010000000111010110100100100010011001010000010001110111110001000011100100100111011011011000100000000101101100111010011101110100001100011000000001001000000111101110001111111001100010000110111000101101111101011001001101100010111100101110011110001000100110111001100001001100101101100111110001101111111111101100000100100111010100010011100110111111110111011011100000001101111001000 1001101110001000010000110001010101100011100010011000010000101011001101011001111100001110000111111100010001100100011101011110111011101110100011011110111100000001011010111011000101101001001100100000100000111100010111111111011010100110100100011001010010011011000001101100001011101011100010101110010110110101011001001000001100001111000010100011000010011110001001111101011100110101000100010000101110100001 0010111000000000011110100100111001101010110111110110000011111111000101110110001111111011111000110001001101100101011011100010001100010100100110001001010001010011110011001110110010010110011111110100010100000101011110100001100100110010000110011100000100110110111011011110001011110111001011111011001010110000011101001000011100101100001110101101001010011011001010000011000000011101010110110011000101101000 1001010010000101111010110111100010011000001000001010011111111111110110010110000010001000010100011111110101010000000000001001110000111111001001001110111010100010011010101011110011100011001000011101101100100101010000101101110101000010100000110100100000001111111001011000100010011101110111000110110101101000111011001011100111111010011010011101001101110110001010100011100101010111011100011101110010010111 1110001000011101101110101001001001101001101111100110011010011111011000001101001110011101000011010110101111101010000000001010111111011111110000111001100010001011110011101110111111011100110001111111111110101110000000010011100111110110110111010100100100010000100101110111100100110110010001101000001101101000101111010010111001111111010000001110110010010011111111111001000100011111101100100100101100000100 1000101000111110110011100001101100011111010010000011000111110111011101000001100001111011000111110100100001100100100110100100010010110100110011000101110011110100100111001110000001101011110000111100110010011010111101000111000010001000110110101010001101010110100110111011010111001010100100000000101000111010000010100010011010101000100110101010001010000011110111000000101110101001011011100011010101011100 0011101001011010111001111101011001010011000001010010111000010110100110010101100111001011101110001101010001001100111001011011111100101010011011101101110110000101001001011000100111000010010001100110001000000101110110011011101111011101011011010000100011110010000111000101010101011111100101010010001010011110100100001001001100011111001101011110001011000110110000110011011110011101001101100011010010010101 0110110101100000000001001101011011011001010000011110001011011001111000100101010100010001110101010011010001100000000100100010010000010001110100111001101001111001011000011101010100101101110111001110001111110001001000001010011011011000011011101100110100001011000000110101000100101010011100011001001110111110101000100000011100010110101101000011110100000001011010110010010000101011100011111010111101010000 1001010001111011000101111000001001010110010000010000110101011110101110010001010101111110010001111110111101010101110001000111101100001001001111101000101000000001001110011110101011111111111111010100000101100011111101111100000001000010101110001000011000110011101001101100010100101110111110110101110000010110111001001110000101010000011010010001000001101010101010101110100111111011010010011110001010011111 0011101010101010000101001000110011001011101100101101101011110111111110100111111001101101100011010010000010011011000001010111101111001110000101110100111011011011101111010011111000111111101010110111111001011110111100011111010000010010110011001011001011011000001010110001111111111100110100001010111101111101000001011101000001101111100110100110111010001000001101101000011000010101100111100110100111001100 0100000100001111101101010010100011111010111111100000001111111001100100110000001101110101110000011110010101000000001011001001100111101001001000111011111101100000001100111101011110011101100000110110000011000100011011100101111101001110000110100011000011100001110010101010000101110011101111101011100001000001010000110010001001100110001110110000001101111000111111101111101011000111100010000010101110100111 0111011100000100111010010101001010111110110000110110000011010000001010111011100011110011000001111001011100001010001110001110110001011001100111110000110011101001100011110001100101001010111110001000001101010110111000000111011110001010001110000010001011010010011011100001101110111010111101011011001100100111010010011010111011111001011110001001111011000101010000101111111000101001110011110100100001101110 0001110011001100001101100010111110111010010111101011001010001001101111010111110001011101101010010101001110111110011110000111001110101010110001010010111110010100111011101011100000001100000010011000101111111001100110000011110000100000101111100001001001011100111010101000111110110011111110100110010110100111101000111011001001111011101100101101111000000011011000010111010010110001011100100110011111010110 1111001111010101010111010111110101101110010001101110110011110111011001101001001001110111110111000111010111101011000100101111101000100101010010111011001001111101110100010001101110111000011110100010000010001011010001011010010011001000101000011000111110101110000110100101111011101100000100111110110101111100111011010000011111110010111110100011011001000000111110001001001101101100111001111001111101010111 1101101101000000101010110000000110101000100110111101100010101001011000001100111001011011010111111101010000001011110001101000111111100010000010111000010110100011010010110010111111010001101001111100101111110001100100011001110100010011100000001101110001000100011001001010111011001000101110110000111111100111110111100001001010100110010011000001111101010000111110111101011001001011100000111101111110010010 1101111001111000101111111110101100110011001001001001100010011100100011111011001111110011001100110110101001010100100101000110111100101110011011110110111110100010000100000011100101001110011000000001111100001110111001100101101000000000010011100000000110100101010101110101101001000100101000100000100000101010111101111000001001110111100101001001011000000111011010110011100101011000001101011001110001110001 0011111010111011111001100110010110011101111011000101010001010111011010010000010011110010100000100100000100011100011110111111100011011010110100100011101100100011000100001100011010111111100111101101100010001001100110001110010010111010000100011001100010001101011101110111101110100010010011010100110011110111001100101010010101100100110110101000000000110000000111101111101010110000101100001010000010001100 1111000111000101001010000110100011111101000000111110110001010000111011111111011101111101010011011100110100000011000111010001101111011000001001101100111100110111010111000100110111111100010001111101011010000101111000110001011010111100010011101100011100111010011101110010111010000001101001101110010100011001111010101000011111010011001101110000001101111010110010111111001110001111001101111011111000111110 1111100101000100000111011101001001011100110001000011110010101111100011001010100010011110110011101100100110001011001000111100001111110001111101010100001000001101000010110011011110100110111010101111000000100101110001011101001110100110101101101001011111110101010011000010011001001101101100001000101100001001101011010101100110100000101100110100011100011011010111011010100011101100110011110000010010111001 1111110100011010000111000010010001001010011010010010101111001010000010111000100110010100101010110111000001011110010001111100001010111111010100100011101111010011000110000100110010101001111111100101110100110100101100011011101111101001011111111001101111000000001110010001111101111001100100101010001111000000110111010100110010111101001000111101001001010010011000100100110110100010110011001000011101110000 1100111010011000001100011101100100011100111111110101101000010010001000111001011010001101110100110101100100010010001101010001001101110010100000010110001010100101110110110010100001001111111101011100010110001000110000000110001101001101010011001110001001000011100011101010101101010000101111000010010110001110111011001111000010011001010001101100111010110100001010011111111110000111001011011000001001101001 0001001111011011111011111000111000000101010110110101000110000100110101101101000010001011011110001110000110101111101001000110011011001000110010110011101010011000111011110010100001000101111001111010101111010001110111100011101101010101000100100001000110001011111001000011100100101100111100100001111010011101111111011100000111010110010100110101110110010111101101011000001110011011001010111011110000001000 1000000101100001011111001101110011111001110001110111101111011110010010010001011001100111001110110100101011001110100011100000010011000111010001011000111000010100101100100111001011011010101100001010000111100000100010010011100001001100010101010110100111111111100000101100101101110111110001000001000001111101010010010000000010010110011111111010001110010101110101011111111000111110010100000001111000110101 1001101101000001011010010110100100101000101010111000100000001100111110100110100111111110011001010011100010101010000000101010000101111101101101100000111010101001101110110011101111010101110110011001001000100101111000011011010110111010001111000001101011101010001011101001101110010111000111011000011000110000001100101111000001101001000010010111000101001101101011110011111001000101100110101011111010001000 0010101001010111010100100011111100111111010101100010100111110110101110011101000010001010010011111010111100010110010101001110100001001001110110000010000011101110101110001011111000000000111001000100101100111000001010100101101000111001011111111011101001001101100001000011110001000001010101000110011001011101001001010110011110100011001010111001100100000010010100010010111111100011110001010001011101000000 1100011111010001001010001001101100010010100010111100001001010100011100101011011111001100011001010100010000110111001000101100110000011011001101000001111011000100100000100001101110011010010110111000001011111011000101101110010001100011111110100100111010011110011101000100101101000011000000010010000001011000000000111100101110110010111010000100000000011111011101011110100111101111010011000001101101111010
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